﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace DiscoveryLogic.UI.Filters
{
    public delegate void RangeSlideValueChanged(double start, double selectedRangeSize, double totalRangeSize);

    public partial class HorizontalRangeFilter : UserControl
    {
        public event RangeSlideValueChanged OnRangeSlideValueChanged;
        #region fields
        private MouseManager rightThumbMouseEventManager;
        private MouseManager leftThumbMouseEventManager;
        private MouseManager visibleRegionMouseManager;
        private double leftSliderThumbCanvasLeftPos;
        private double rightSliderThumbCanvasLeftPos;
        private double visibleRegionLeftPos;
        private double visibleRegionOverlayLeftPos;
        #endregion

        public HorizontalRangeFilter()
        {
            InitializeComponent();

            this.visibleRegionLeftPos = (double) this.VisibleRegion.GetValue(Canvas.LeftProperty);
            this.visibleRegionOverlayLeftPos = (double) this.VisibleRegionOverlay.GetValue(Canvas.LeftProperty);
            this.leftSliderThumbCanvasLeftPos = (double) this.LeftSliderThumbCanvas.GetValue(Canvas.LeftProperty);
            this.rightSliderThumbCanvasLeftPos = (double) this.RightSliderThumbCanvas.GetValue(Canvas.LeftProperty);

            // initialize mouse manager that controls dragging
            this.rightThumbMouseEventManager=new MouseManager("horizontal",0,this.SliderBar.Width,this.RightSliderThumbCanvas.Width);
            this.leftThumbMouseEventManager = new MouseManager("horizontal", 0, this.SliderBar.Width, this.LeftSliderThumbCanvas.Width);
            this.visibleRegionMouseManager=new MouseManager("horizontal",0,this.SliderBar.Width,this.VisibleRegionOverlay.Width);
            this.AttachHandlers();
        }

        #region event handlers
        private void AttachHandlers()
        {
            this.rightThumbMouseEventManager.sliderMove += new MouseManager.SliderMoveEventHandler(RightThumbMouseEventManager_sliderMove);
            this.leftThumbMouseEventManager.sliderMove += new MouseManager.SliderMoveEventHandler(LeftThumbMouseEventManager_sliderMove);
            this.visibleRegionMouseManager.sliderMove += new MouseManager.SliderMoveEventHandler(visibleRegionMouseManager_sliderMove);

            this.RightSliderThumbCanvas.MouseEnter += this.rightThumbMouseEventManager.OnMouseEnterHand;
            this.RightSliderThumbCanvas.MouseLeave += this.rightThumbMouseEventManager.OnMouseLeaveArrow;
            this.RightSliderThumbCanvas.MouseLeftButtonDown += this.rightThumbMouseEventManager.SliderMouseDown;
            this.RightSliderThumbCanvas.MouseLeftButtonUp += this.rightThumbMouseEventManager.SliderMouseUp;
            this.RightSliderThumbCanvas.MouseMove += this.rightThumbMouseEventManager.SliderMouseMove;

            this.LeftSliderThumbCanvas.MouseEnter += this.leftThumbMouseEventManager.OnMouseEnterHand;
            this.LeftSliderThumbCanvas.MouseLeave += this.leftThumbMouseEventManager.OnMouseLeaveArrow;
            this.LeftSliderThumbCanvas.MouseLeftButtonDown += this.leftThumbMouseEventManager.SliderMouseDown;
            this.LeftSliderThumbCanvas.MouseLeftButtonUp += this.leftThumbMouseEventManager.SliderMouseUp;
            this.LeftSliderThumbCanvas.MouseMove += this.leftThumbMouseEventManager.SliderMouseMove;

            this.VisibleRegionOverlay.MouseEnter += this.visibleRegionMouseManager.OnMouseEnterHand;
            this.VisibleRegionOverlay.MouseLeave += this.visibleRegionMouseManager.OnMouseLeaveArrow;
            this.VisibleRegionOverlay.MouseLeftButtonDown += this.visibleRegionMouseManager.SliderMouseDown;
            this.VisibleRegionOverlay.MouseLeftButtonUp += this.visibleRegionMouseManager.SliderMouseUp;
            this.VisibleRegionOverlay.MouseMove += this.visibleRegionMouseManager.SliderMouseMove;

        }

        void visibleRegionMouseManager_sliderMove(object sender, CustomEventArgs eventArgs)
        {
            CustomEventArgs args = (CustomEventArgs)eventArgs;

            double newPosition = args.SliderThumbValue;
            // Check that the new position doesn't exceed bounds
            if (newPosition < 0)
            {
                newPosition = 0;
            }
            else if (newPosition + VisibleRegion.Width > this.HSliderZoomer1.Width)
            {
                newPosition = this.HSliderZoomer1.Width - VisibleRegion.Width;
            }

            // Set position
            visibleRegionLeftPos = newPosition;
            VisibleRegion.SetValue(Canvas.LeftProperty, visibleRegionLeftPos);

            visibleRegionOverlayLeftPos = newPosition;
            VisibleRegionOverlay.SetValue(Canvas.LeftProperty, visibleRegionOverlayLeftPos);

            // Set slider thumb and slider thumb dividers positions as well
            leftSliderThumbCanvasLeftPos = newPosition - (LeftSliderThumbCanvas.Width / 2);
            LeftSliderThumbCanvas.SetValue(Canvas.LeftProperty, leftSliderThumbCanvasLeftPos);

            rightSliderThumbCanvasLeftPos = newPosition + VisibleRegion.Width - (RightSliderThumbCanvas.Width / 2);
            RightSliderThumbCanvas.SetValue(Canvas.LeftProperty, rightSliderThumbCanvasLeftPos);

            if (this.OnRangeSlideValueChanged != null)
            {
                double w = this.HSliderZoomer1.Width;
                double xPct = this.leftSliderThumbCanvasLeftPos / w;
                double wPct = (this.rightSliderThumbCanvasLeftPos - this.leftSliderThumbCanvasLeftPos) / w;
                this.OnRangeSlideValueChanged(xPct, wPct, this.SliderBar.Width);
            }
        }

        void LeftThumbMouseEventManager_sliderMove(object sender, CustomEventArgs eventArgs)
        {
            CustomEventArgs args = (CustomEventArgs)eventArgs;

            double newPosition = args.SliderThumbValue;

            // If new position is greater than the right slider thumb position
            if (newPosition > rightSliderThumbCanvasLeftPos - RightSliderThumbCanvas.Width)
            {
                newPosition = rightSliderThumbCanvasLeftPos - RightSliderThumbCanvas.Width;
            }

            // Set position of slider thumb
            leftSliderThumbCanvasLeftPos = newPosition;
            LeftSliderThumbCanvas.SetValue(Canvas.LeftProperty, leftSliderThumbCanvasLeftPos);
            // Position the visible blue region
            PositionVisibleRegion();

            if (this.OnRangeSlideValueChanged != null)
            {
                double w = this.HSliderZoomer1.Width;
                double xPct = this.leftSliderThumbCanvasLeftPos / w;
                double wPct = (this.rightSliderThumbCanvasLeftPos - this.leftSliderThumbCanvasLeftPos) / w;
                this.OnRangeSlideValueChanged(xPct, wPct, this.SliderBar.Width);
            }
        }

        void RightThumbMouseEventManager_sliderMove(object sender, CustomEventArgs eventArgs)
        {
            CustomEventArgs args = (CustomEventArgs) eventArgs;
            double newPosition = args.SliderThumbValue;
            // If new position is less than the left slider thumb position
            if (newPosition < leftSliderThumbCanvasLeftPos + LeftSliderThumbCanvas.Width)
            {
                newPosition = leftSliderThumbCanvasLeftPos + LeftSliderThumbCanvas.Width;
            }

            if (newPosition > this.HSliderZoomer1.Width)
                newPosition = this.HSliderZoomer1.Width;

            // Set position of slider thumb
            rightSliderThumbCanvasLeftPos = newPosition;
            RightSliderThumbCanvas.SetValue(Canvas.LeftProperty, rightSliderThumbCanvasLeftPos);
            // Position the visible blue region
            PositionVisibleRegion();

            if (this.OnRangeSlideValueChanged != null)
            {
                double w = this.HSliderZoomer1.Width;
                double xPct = this.leftSliderThumbCanvasLeftPos / w;
                double wPct = (this.rightSliderThumbCanvasLeftPos - this.leftSliderThumbCanvasLeftPos) / w;
                double totalRange = this.SliderBar.Width;
                this.OnRangeSlideValueChanged(xPct, wPct, totalRange);
            }
        }
        #endregion

        #region private methods
        /// <summary>
        /// Position and set width of the blue visible region between the two sliders
        /// </summary>
        private void PositionVisibleRegion()
        {
            VisibleRegion.Width = rightSliderThumbCanvasLeftPos - leftSliderThumbCanvasLeftPos;
            VisibleRegionOverlay.Width = VisibleRegion.Width;

            visibleRegionLeftPos = leftSliderThumbCanvasLeftPos + (LeftSliderThumbCanvas.Width / 2);
            VisibleRegion.SetValue(Canvas.LeftProperty, visibleRegionLeftPos);

            visibleRegionOverlayLeftPos = leftSliderThumbCanvasLeftPos + (LeftSliderThumbCanvas.Width / 2);
            VisibleRegionOverlay.SetValue(Canvas.LeftProperty, visibleRegionOverlayLeftPos);
        }
        #endregion
    }
}
